<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\Question;
use app\common\model\QuestionErrorNum;
use app\common\model\UserAnswers;
use think\Db;

/**
 * 错题信息
 * @package app\api\controller
 */
class QuestionError extends Api
{
    protected $noNeedLogin = [''];
    protected $noNeedRight = ['*'];


    /**
     * 获取刷错题总次数
     * @return void 
     */
    public function getErrorCount()
    {
        $user_id = $this->auth->id;
        $count = (new QuestionErrorNum())->getTotalErrorBookCount($user_id);
        $this->success('success', ['total_count' => $count]);
    }


    /**
     * 错题信息
     * @return void
     */
    public function index()
    {
        $user_id = $this->auth->id;
        $mock_id = $this->request->param('mock_id'); # 模块id
        if (!$mock_id) {
            $this->error('模块id不能为空');
        }
        $list = (new UserAnswers())->getErrorList($user_id, $mock_id);
        if (empty($list)) {
            $this->error('没有错题');
        }
        # 记录错题次数
        $demo = (new QuestionErrorNum())->recordErrorBookAccess($user_id);
        $this->success('success', $list);
    }
    
    /**
     * 查询所有错题集
     * @return void
     */
    public function getErrorQuestionList()
    {
        $user_id = $this->auth->id;
        $list = (new UserAnswers())->getErrorList($user_id, 0, 1);
        $this->success('错题集', $list);
    }

    /**
     * 拍照上传
     * @return void 
     */
    public function photoupload()
    {
        $mock_id = $this->request->param('mock_id');
        if (!$mock_id) {
            $this->error('模块id不能为空');
        }
        $img = $this->request->param('img');
        if (!$img) {
            $this->error('图片不能为空');
        }
        $user_id = $this->auth->id;
        $row = Db::name('user_answers')->insert([
            'user_id' => $user_id,
            'mock_id' => $mock_id,
            'photo_img' => $img,
            'is_right' => 0,
            'in_error' => 1,
            'type' => 2,
            'create_time' => time(),
        ]);
        $this->success('success', $row);
    }


    /**
     * 题目预览（用于Word下载）
     * @return void 
     */
    public function preview()
    {
        $question_ids = $this->request->param('question_ids');
        if (!$question_ids) {
            $this->error('题目id不能为空');
        }
        $question_ids = explode(',', $question_ids);

        // 只查询普通题目（type != 2），拍照题不参与预览
        $normalQuestions = Db::name('user_answers')
            ->whereIn('question_id', $question_ids)
            ->where('type', '<>', 2) // 排除拍照题
            ->field('id as question_user_answers_id,question_id,answer,is_right,type')
            ->select();

        $questionList = [];
        if (!empty($normalQuestions)) {
            $questionIds = array_column((array)$normalQuestions, 'question_id');
            $questionUserAnswers = [];
            foreach ($normalQuestions as $answer) {
                $questionUserAnswers[$answer['question_id']] = $answer;
            }
            $question = new Question();
            $questionList = $question->getListQuestion(['id' => $questionIds], $questionUserAnswers);
        }
        if (empty($questionList)) {
            $this->error('没有可预览的题目');
        }
        $this->success('success', $questionList);
    }



    /**
     * 下载Word文档或生成预览页面
     * @return void
     */
    public function downloadWord()
    {
        $question_ids = $this->request->param('question_ids');
        $type = $this->request->param('type'); // 1=预览页面，2=下载Word
        $showExplain = $this->request->param('showExplain', false); // 是否显示解析
        if (empty($question_ids)) {
            $this->error('请选择要下载的题目');
        }
        if (!in_array($type, [1, 2])) {
            $this->error('类型参数错误：1=预览页面，2=下载Word');
        }
        // 获取题目数据
        $questionList = $this->getQuestionList($question_ids);
        if (empty($questionList)) {
            $this->error('没有找到相关题目数据');
        }
        if ($type == 1) {
            // 预览模式：生成HTML页面，返回预览地址
            $data = $this->generatePreviewPage($questionList, $showExplain);
        } else {
            // 下载模式：生成Word文档，返回下载地址
            $data = $this->generateWordDocument($questionList, $showExplain);
            if ($data) {
                # 保存 记录
                $data['user_id'] = $this->auth->id;
                Db::name('user_word')->insert($data);
            }
        }
        $this->success('success', $data);
    }


    /**
     * 获取题目列表数据
     * @param string $question_ids 题目ID字符串
     * @return array
     */
    private function getQuestionList($question_ids)
    {
        $question_ids = explode(',', $question_ids);

        // 只查询普通题目（type != 2），拍照题不参与下载
        $normalQuestions = Db::name('user_answers')
            ->whereIn('question_id', $question_ids)
            ->where('type', '<>', 2) // 排除拍照题
            ->field('id as question_user_answers_id,question_id,answer,is_right,type')
            ->select();

        $questionList = [];
        if (!empty($normalQuestions)) {
            $questionIds = array_column($normalQuestions, 'question_id');
            $questionUserAnswers = [];
            foreach ($normalQuestions as $answer) {
                $questionUserAnswers[$answer['question_id']] = $answer;
            }
            $question = new Question();
            $questionList = $question->getListQuestion(['id' => $questionIds], $questionUserAnswers);
        }

        return $questionList;
    }

    /**
     * 生成预览页面
     * @param array $questions 题目列表
     */
    private function generatePreviewPage($questions, $showExplain)
    {
        try {
            // 定义根路径
            $rootPath = defined('ROOT_PATH') ? ROOT_PATH : dirname(dirname(dirname(__DIR__)));

            // 创建临时目录
            $tempDir = $rootPath . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'html';
            if (!is_dir($tempDir)) {
                if (!mkdir($tempDir, 0755, true)) {
                    throw new \Exception('无法创建临时目录：' . $tempDir);
                }
            }

            // 检查目录权限
            if (!is_writable($tempDir)) {
                throw new \Exception('临时目录无写入权限：' . $tempDir);
            }

            // 生成HTML内容
            $html = $this->generateHtmlContent($questions, $showExplain);

            // 生成文件名
            $filename = '错题集预览_' . date('YmdHis') . '_' . uniqid() . '.html';
            $filePath = $tempDir . DIRECTORY_SEPARATOR . $filename;

            // 保存HTML文件
            if (file_put_contents($filePath, $html) === false) {
                throw new \Exception('HTML预览页面保存失败');
            }

            // 检查文件是否生成成功
            if (!file_exists($filePath)) {
                throw new \Exception('HTML预览页面文件生成失败');
            }

            // 检查文件大小
            $fileSize = filesize($filePath);
            if ($fileSize === false || $fileSize == 0) {
                throw new \Exception('生成的HTML预览页面文件为空或无效');
            }
            // 返回预览地址
            $previewUrl = '/temp/html/' . $filename;

            // 清理超过5分钟的旧HTML文件
            $this->cleanOldHtmlFiles();
        } catch (\Exception $e) {
            $this->error('生成预览页面失败：' . $e->getMessage());
        }
        $this->success('预览页面生成成功', [
            'preview_url' => $this->request->domain() . $previewUrl,
            'filename' => $filename,
            'file_size' => number_format($fileSize / 1024, 2) . ' KB',
            'expire_time' => date('Y-m-d H:i:s', time() + 300), // 5分钟后过期
            'file_type' => 'html',
            'note' => '预览页面已生成，可通过链接访问，5分钟后自动清理'
        ]);
    }



    /**
     * 生成HTML内容
     * @param array $questions 题目列表
     * @return string
     */
    private function generateHtmlContent($questions, $showExplain)
    {
        $html = '<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>错题集</title>
    <style>
        * { box-sizing: border-box; }
        body { 
            font-family: "Microsoft YaHei", Arial, sans-serif; 
            margin: 0; 
            padding: 0;
            background: #f5f5f5; 
            min-height: 100vh;
            width: 100%;
        }
        .container { 
            width: 100%; 
            min-height: 100vh;
            background: white; 
            padding: 15px; 
        }
        .header { 
            text-align: center; 
            margin-bottom: 20px; 
            padding-bottom: 15px; 
            border-bottom: 2px solid #007bff; 
        }
        .header h1 { 
            color: #007bff; 
            margin: 0 0 10px 0; 
            font-size: 24px; 
        }
        .header p {
            margin: 0;
            color: #666;
            font-size: 14px;
        }
        .question { 
            margin-bottom: 20px; 
            padding: 15px; 
            border: 1px solid #e9ecef; 
            border-radius: 8px; 
            background: #fafafa; 
        }
        .question-header { 
            margin-bottom: 15px; 
        }
        .question-title { 
            font-size: 16px; 
            font-weight: bold; 
            color: #333; 
            line-height: 1.6; 
            display: flex;
            align-items: flex-start;
        }
        .question-number {
            color: #007bff;
            font-weight: bold;
            margin-right: 8px;
            flex-shrink: 0;
        }
        .question-title img { 
            max-width: 100%; 
            height: auto; 
            margin: 10px 0; 
            border-radius: 5px; 
            box-shadow: 0 2px 5px rgba(0,0,0,0.1); 
        }
        .options { 
            margin: 15px 0; 
        }
        .option { 
            margin: 8px 0; 
            padding: 10px 12px; 
            border-radius: 5px; 
            border: 1px solid #e9ecef;
            background: white;
        }
        .option.correct { 
            background: #d4edda; 
            border-left: 4px solid #28a745; 
        }
        .option.user-answer { 
            background: #f8d7da; 
            border-left: 4px solid #dc3545; 
            font-weight: bold; 
        }
        .option.correct.user-answer { 
            background: #d4edda; 
            border-left: 4px solid #28a745; 
        }
        .answer-info { 
            margin-top: 15px; 
            padding: 15px; 
            background: #e9ecef; 
            border-radius: 5px; 
        }
        .user-answer { 
            color: #dc3545; 
            margin-bottom: 8px; 
            font-size: 14px;
        }
        .correct-answer { 
            color: #28a745; 
            margin-bottom: 8px; 
            font-size: 14px;
        }
        .explain { 
            color: #6c757d; 
            font-style: italic; 
            line-height: 1.6; 
            margin-top: 10px;
            padding-top: 10px;
            border-top: 1px solid #dee2e6;
        }
        .explain img { 
            max-width: 100%; 
            height: auto; 
            margin: 10px 0; 
            border-radius: 5px; 
            box-shadow: 0 2px 5px rgba(0,0,0,0.1); 
        }
        .image { 
            max-width: 100%; 
            height: auto; 
            margin: 10px 0; 
            border-radius: 5px; 
            box-shadow: 0 2px 5px rgba(0,0,0,0.1); 
        }
        /* 富文本样式 */
        .rich-text { 
            line-height: 1.6; 
        }
        .rich-text p { 
            margin: 8px 0; 
        }
        .rich-text strong, .rich-text b { 
            font-weight: bold; 
        }
        .rich-text em, .rich-text i { 
            font-style: italic; 
        }
        .rich-text u { 
            text-decoration: underline; 
        }
        .rich-text ul, .rich-text ol { 
            margin: 10px 0; 
            padding-left: 20px; 
        }
        .rich-text li { 
            margin: 5px 0; 
        }
        .rich-text blockquote { 
            border-left: 4px solid #007bff; 
            padding-left: 15px; 
            margin: 15px 0; 
            color: #666; 
        }
        .rich-text table { 
            border-collapse: collapse; 
            width: 100%; 
            margin: 15px 0; 
        }
        .rich-text th, .rich-text td { 
            border: 1px solid #ddd; 
            padding: 8px; 
            text-align: left; 
        }
        .rich-text th { 
            background-color: #f8f9fa; 
        }
        /* 图片样式优化 */
        .rich-text img { 
            max-width: 100%; 
            height: auto; 
            margin: 10px 0; 
            border-radius: 5px; 
            box-shadow: 0 2px 5px rgba(0,0,0,0.1); 
            display: block; 
        }
        
        /* 移动端优化 */
        @media (max-width: 768px) { 
            .container { 
                padding: 10px; 
            }
            .question { 
                padding: 12px; 
                margin-bottom: 15px;
            }
            .header h1 {
                font-size: 20px;
            }
            .question-title {
                font-size: 15px;
            }
            .option {
                padding: 8px 10px;
            }
            .answer-info {
                padding: 12px;
            }
        }
        
        /* 打印样式 */
        @media print { 
            body { 
                background: white; 
            } 
            .container { 
                box-shadow: none; 
            } 
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>错题集</h1>
            <p>生成时间：' . date('Y-m-d H:i:s') . '</p>
        </div>';

        foreach ($questions as $index => $question) {
            $questionNum = $index + 1;

            $html .= '
        <div class="question">
            <div class="question-header">
                <div class="question-title rich-text"><span class="question-number">' . $questionNum . '.</span>' . $this->sanitizeHtml($question['title']) . '</div>
            </div>';

            // 处理选项
            if (!empty($question['options_json']) && is_array($question['options_json'])) {
                $html .= '<div class="options">';
                foreach ($question['options_json'] as $option) {
                    $optionClass = 'option';
                    if ($option['is_correct']) {
                        $optionClass .= ' correct';
                    }
                    if (isset($question['user_answer']) && $question['user_answer'] == $option['key']) {
                        $optionClass .= ' user-answer';
                    }

                    $html .= '<div class="' . $optionClass . '">';
                    $html .= '<strong>' . htmlspecialchars($option['key']) . '.</strong> ';

                    // 处理选项文本（可能包含富文本）
                    if (!empty($option['text'])) {
                        $html .= '<span class="rich-text">' . $this->sanitizeHtml($option['text']) . '</span>';
                    }

                    // 添加选项图片字段
                    if (!empty($option['image'])) {
                        $html .= '<br><img src="' . htmlspecialchars($option['image']) . '" class="image" alt="选项图片">';
                    }

                    $html .= '</div>';
                }
                $html .= '</div>';
            }

            // 答案信息
            $html .= '
            <div class="answer-info">
                <div class="user-answer"><strong>你的答案：</strong>' . htmlspecialchars($question['user_answer'] ?? '未作答') . '</div>
                <div class="correct-answer"><strong>正确答案：</strong>' . htmlspecialchars($question['answer']) . '</div>';

            // 根据字段判断是否显示解析（这里可以根据实际需求修改判断条件）
            if ($showExplain && !empty($question['explain'])) {
                $html .= '<div class="explain rich-text"><strong>解析：</strong>' . $this->sanitizeHtml($question['explain']) . '</div>';
            }

            $html .= '</div>
        </div>';
        }

        $html .= '
    </div>
</body>
</html>';

        return $html;
    }



    /**
     * 安全处理HTML内容，允许安全的HTML标签
     * @param string $html HTML内容
     * @return string 处理后的HTML
     */
    private function sanitizeHtml($html)
    {
        if (empty($html)) {
            return '';
        }

        // 允许的安全HTML标签和属性
        $allowedTags = [
            'p' => ['class', 'style'],
            'br' => [],
            'strong' => ['class', 'style'],
            'b' => ['class', 'style'],
            'em' => ['class', 'style'],
            'i' => ['class', 'style'],
            'u' => ['class', 'style'],
            'ul' => ['class', 'style'],
            'ol' => ['class', 'style'],
            'li' => ['class', 'style'],
            'blockquote' => ['class', 'style'],
            'table' => ['class', 'style', 'width'],
            'thead' => ['class', 'style'],
            'tbody' => ['class', 'style'],
            'tr' => ['class', 'style'],
            'th' => ['class', 'style', 'colspan', 'rowspan'],
            'td' => ['class', 'style', 'colspan', 'rowspan'],
            'img' => ['src', 'alt', 'title', 'width', 'height', 'class', 'style'],
            'span' => ['class', 'style'],
            'div' => ['class', 'style'],
            'h1' => ['class', 'style'],
            'h2' => ['class', 'style'],
            'h3' => ['class', 'style'],
            'h4' => ['class', 'style'],
            'h5' => ['class', 'style'],
            'h6' => ['class', 'style']
        ];

        // 允许的安全CSS属性
        $allowedStyles = [
            'color',
            'background-color',
            'font-size',
            'font-weight',
            'font-style',
            'text-align',
            'text-decoration',
            'line-height',
            'margin',
            'padding',
            'border',
            'border-radius',
            'width',
            'height',
            'max-width',
            'max-height'
        ];

        // 清理HTML标签
        $html = strip_tags($html, '<' . implode('><', array_keys($allowedTags)) . '>');

        // 清理HTML属性
        $html = preg_replace_callback('/<([a-z][a-z0-9]*)[^>]*>/i', function ($matches) use ($allowedTags) {
            $tag = strtolower($matches[1]);
            if (!isset($allowedTags[$tag])) {
                return '';
            }

            $allowedAttrs = $allowedTags[$tag];
            $tagContent = $matches[0];

            // 提取属性
            preg_match_all('/([a-z][a-z0-9]*)\s*=\s*["\']([^"\']*)["\']/i', $tagContent, $attrMatches, PREG_SET_ORDER);

            $cleanAttrs = [];
            foreach ($attrMatches as $attrMatch) {
                $attrName = strtolower($attrMatch[1]);
                $attrValue = $attrMatch[2];

                if (in_array($attrName, $allowedAttrs)) {
                    // 特殊处理style属性
                    if ($attrName === 'style') {
                        $attrValue = $this->sanitizeCss($attrValue);
                    }
                    $cleanAttrs[] = $attrName . '="' . htmlspecialchars($attrValue) . '"';
                }
            }

            if (!empty($cleanAttrs)) {
                return '<' . $tag . ' ' . implode(' ', $cleanAttrs) . '>';
            } else {
                return '<' . $tag . '>';
            }
        }, $html);

        return $html;
    }

    /**
     * 清理CSS样式，只允许安全的属性
     * @param string $css CSS样式字符串
     * @return string 清理后的CSS
     */
    private function sanitizeCss($css)
    {
        $allowedStyles = [
            'color',
            'background-color',
            'font-size',
            'font-weight',
            'font-style',
            'text-align',
            'text-decoration',
            'line-height',
            'margin',
            'padding',
            'border',
            'border-radius',
            'width',
            'height',
            'max-width',
            'max-height'
        ];

        $cleanCss = [];
        $stylePairs = explode(';', $css);

        foreach ($stylePairs as $pair) {
            $pair = trim($pair);
            if (empty($pair)) continue;

            $colonPos = strpos($pair, ':');
            if ($colonPos === false) continue;

            $property = trim(substr($pair, 0, $colonPos));
            $value = trim(substr($pair, $colonPos + 1));

            if (in_array(strtolower($property), $allowedStyles)) {
                $cleanCss[] = $property . ':' . $value;
            }
        }

        return implode(';', $cleanCss);
    }

    /**
     * 生成Word文档
     * @param array $questions 题目列表
     */
    private function generateWordDocument($questions, $showExplain)
    {
        // 检查是否安装了PHPWord扩展
        if (!class_exists('PhpOffice\PhpWord\PhpWord')) {
            $this->error('未安装PHPWord扩展，无法生成Word文档。请先安装PHPWord扩展。');
        }

        try {
            // 定义根路径
            $rootPath = defined('ROOT_PATH') ? ROOT_PATH : dirname(dirname(dirname(__DIR__)));

            $phpWord = new \PhpOffice\PhpWord\PhpWord();

            // 设置文档属性
            $properties = $phpWord->getDocInfo();
            $properties->setCreator('错题系统');
            $properties->setTitle('错题集');
            $properties->setDescription('用户错题汇总');

            // 创建页面
            $section = $phpWord->addSection();

            // 添加标题
            $section->addText('错题集', ['bold' => true, 'size' => 18], ['alignment' => 'center']);
            $section->addTextBreak(1);

            foreach ($questions as $index => $question) {
                $questionNum = $index + 1;
                // $typeText = $this->getQuestionTypeText($question['kind']);

                // // 题目类型
                // $section->addText($typeText, ['bold' => true, 'color' => '007bff'], ['indent' => 0.5]);

                // 题目内容（处理富文本和图片）
                $titleText = $questionNum . '. ' . $this->stripHtmlTags($question['title']);
                $section->addText($titleText, ['bold' => true, 'size' => 12]);

                // 添加题干中的图片
                $this->addImagesFromHtml($section, $question['title'], $rootPath);

                // 处理选项
                if (!empty($question['options_json']) && is_array($question['options_json'])) {
                    foreach ($question['options_json'] as $option) {
                        $optionText = $option['key'] . '. ' . $this->stripHtmlTags($option['text']);
                        $textStyle = [];

                        if ($option['is_correct']) {
                            $textStyle['color'] = '28a745'; // 正确答案用绿色
                        }
                        if (isset($question['user_answer']) && $question['user_answer'] == $option['key']) {
                            $textStyle['bold'] = true; // 用户答案加粗
                        }

                        $section->addText($optionText, $textStyle, ['indent' => 1]);

                        // 添加选项文本中的图片
                        if (!empty($option['text'])) {
                            $this->addImagesFromHtml($section, $option['text'], $rootPath);
                        }

                        // 添加选项图片字段
                        if (!empty($option['image'])) {
                            $this->addImageToWord($section, $option['image'], $rootPath);
                        }
                    }
                }

                // 答案信息
                $section->addTextBreak(1);
                $section->addText('你的答案：' . ($question['user_answer'] ?? '未作答'), ['color' => 'dc3545']);
                $section->addText('正确答案：' . $question['answer'], ['color' => '28a745']);

                if (!empty($question['explain']) && $showExplain) {
                    $explainText = '解析：' . $this->stripHtmlTags($question['explain']);
                    $section->addText($explainText, ['italic' => true, 'color' => '6c757d']);
                    // 添加解析中的图片
                    $this->addImagesFromHtml($section, $question['explain'], $rootPath);
                }
                $section->addTextBreak(2);
            }
            // 创建临时目录
            $tempDir = $rootPath . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'word';
            if (!is_dir($tempDir)) {
                if (!mkdir($tempDir, 0755, true)) {
                    throw new \Exception('无法创建临时目录：' . $tempDir);
                }
            }
            // 检查目录权限
            if (!is_writable($tempDir)) {
                throw new \Exception('临时目录无写入权限：' . $tempDir);
            }

            // 生成文件名
            $filename = '错题集_' . date('YmdHis') . '_' . uniqid() . '.docx';
            $filePath = $tempDir . DIRECTORY_SEPARATOR . $filename;

            // 保存文档到临时文件
            $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
            $objWriter->save($filePath);

            // 检查文件是否生成成功
            if (!file_exists($filePath)) {
                throw new \Exception('Word文档文件生成失败');
            }

            // 检查文件大小
            $fileSize = filesize($filePath);
            if ($fileSize === false || $fileSize == 0) {
                throw new \Exception('生成的Word文档文件为空或无效');
            }
            // 返回下载链接
            $downloadUrl = '/temp/word/' . $filename;
        } catch (\Exception $e) {
            // 记录详细错误信息
            error_log('Word文档生成失败: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
            $this->error('生成Word文档失败：' . $e->getMessage());
        }
        return [
            'download_url' => $downloadUrl,
            'filename' => $filename,
            'file_size' => number_format($fileSize / 1024, 2) . ' KB',
            'expire_time' => date('Y-m-d H:i:s', time() + 3600), // 1小时后过期
            'temp_dir' => $tempDir,
            'file_path' => $filePath
        ];
    }

    /**
     * 从HTML内容中提取并添加图片到Word文档
     * @param \PhpOffice\PhpWord\Element\Section $section Word文档段落
     * @param string $html HTML内容
     * @param string $rootPath 根路径
     */
    private function addImagesFromHtml($section, $html, $rootPath)
    {
        if (empty($html)) {
            return;
        }

        error_log('从HTML中提取图片，HTML长度: ' . strlen($html));

        // 提取img标签，支持多种格式
        $patterns = [
            '/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i',
            '/<img[^>]+src=([^\s>]+)[^>]*>/i'
        ];

        $foundImages = [];
        foreach ($patterns as $pattern) {
            preg_match_all($pattern, $html, $matches);
            if (!empty($matches[1])) {
                $foundImages = array_merge($foundImages, $matches[1]);
            }
        }

        // 去重
        $foundImages = array_unique($foundImages);

        error_log('找到图片数量: ' . count($foundImages));

        if (!empty($foundImages)) {
            foreach ($foundImages as $imageSrc) {
                error_log('处理HTML中的图片: ' . $imageSrc);
                $this->addImageToWord($section, $imageSrc, $rootPath);
            }
        } else {
            error_log('HTML中未找到图片标签');
        }
    }

    /**
     * 下载网络图片到本地临时目录
     * @param string $imageUrl 图片URL
     * @param string $rootPath 根路径
     * @return string|false 本地图片路径，失败返回false
     */
    private function downloadImageToTemp($imageUrl, $rootPath)
    {
        try {
            // 创建临时图片目录
            $tempImageDir = $rootPath . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'images';
            if (!is_dir($tempImageDir)) {
                if (!mkdir($tempImageDir, 0755, true)) {
                    error_log('创建临时图片目录失败: ' . $tempImageDir);
                    return false;
                }
            }

            // 生成唯一的文件名
            $extension = pathinfo(parse_url($imageUrl, PHP_URL_PATH), PATHINFO_EXTENSION);
            if (empty($extension)) {
                $extension = 'jpg'; // 默认扩展名
            }
            $filename = 'img_' . uniqid() . '_' . time() . '.' . $extension;
            $localPath = $tempImageDir . DIRECTORY_SEPARATOR . $filename;

            // 下载图片
            $imageContent = file_get_contents($imageUrl);
            if ($imageContent === false) {
                error_log('下载图片失败: ' . $imageUrl);
                return false;
            }
            // 保存到本地
            if (file_put_contents($localPath, $imageContent) === false) {
                error_log('保存图片到本地失败: ' . $localPath);
                return false;
            }
            error_log('图片下载成功: ' . $imageUrl . ' -> ' . $localPath);
            return $localPath;
        } catch (\Exception $e) {
            error_log('下载图片异常: ' . $e->getMessage() . ' - URL: ' . $imageUrl);
            return false;
        }
    }

    /**
     * 添加图片到Word文档
     * @param \PhpOffice\PhpWord\Element\Section $section Word文档段落
     * @param string $imageSrc 图片路径
     * @param string $rootPath 根路径
     */
    private function addImageToWord($section, $imageSrc, $rootPath)
    {
        try {
            // 记录原始图片路径
            error_log('处理图片: ' . $imageSrc);

            // 处理图片路径
            $imagePath = '';
            if (strpos($imageSrc, 'http') === 0) {
                // 网络图片，下载到本地临时目录
                $imagePath = $this->downloadImageToTemp($imageSrc, $rootPath);
                if (empty($imagePath)) {
                    error_log('下载网络图片失败: ' . $imageSrc);
                    return;
                }
                error_log('网络图片已下载到: ' . $imagePath);
            } elseif (strpos($imageSrc, '/') === 0) {
                // 绝对路径（相对于网站根目录）
                $imagePath = $rootPath . DIRECTORY_SEPARATOR . 'public' . str_replace('/', DIRECTORY_SEPARATOR, $imageSrc);
            } else {
                // 相对路径
                $imagePath = $rootPath . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $imageSrc);
            }

            error_log('解析后的图片路径: ' . $imagePath);

            // 检查文件是否存在和可读
            if (!file_exists($imagePath)) {
                error_log('图片文件不存在: ' . $imagePath);
                return;
            }

            if (!is_readable($imagePath)) {
                error_log('图片文件不可读: ' . $imagePath);
                return;
            }

            // 获取图片信息
            $imageInfo = getimagesize($imagePath);
            if ($imageInfo === false) {
                error_log('无法获取图片信息: ' . $imagePath);
                return;
            }

            $width = $imageInfo[0];
            $height = $imageInfo[1];
            $imageType = $imageInfo[2];

            error_log('图片信息: ' . $width . 'x' . $height . ', 类型: ' . $imageType);

            // 检查图片类型是否支持
            if (!in_array($imageType, [IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF])) {
                error_log('不支持的图片类型: ' . $imageType . ' for ' . $imagePath);
                return;
            }

            // 限制图片大小，避免过大
            $maxWidth = 400;
            $maxHeight = 300;

            if ($width > $maxWidth || $height > $maxHeight) {
                $ratio = min($maxWidth / $width, $maxHeight / $height);
                $width = round($width * $ratio);
                $height = round($height * $ratio);
                error_log('调整图片尺寸: ' . $width . 'x' . $height);
            }

            // 添加图片到Word文档
            $section->addImage($imagePath, [
                'width' => $width,
                'height' => $height,
                'alignment' => 'center'
            ]);

            error_log('成功添加图片到Word: ' . $imagePath);

            // 添加换行
            $section->addTextBreak(1);
        } catch (\Exception $e) {
            // 图片添加失败，记录详细错误信息
            error_log('添加图片到Word失败: ' . $e->getMessage() . ' - 图片路径: ' . $imageSrc . ' - 解析路径: ' . ($imagePath ?? 'N/A') . ' - 错误位置: ' . $e->getFile() . ':' . $e->getLine());
        }
    }

    /**
     * 去除HTML标签，保留纯文本内容
     * @param string $html HTML内容
     * @return string 纯文本内容
     */
    private function stripHtmlTags($html)
    {
        if (empty($html)) {
            return '';
        }

        // 替换一些常见的HTML实体
        $html = str_replace(
            ['&nbsp;', '&amp;', '&lt;', '&gt;', '&quot;', '&#39;'],
            [' ', '&', '<', '>', '"', "'"],
            $html
        );

        // 去除HTML标签，保留文本内容
        $text = strip_tags($html);

        // 清理多余的空白字符
        $text = preg_replace('/\s+/', ' ', $text);
        $text = trim($text);

        return $text;
    }



    /**
     * 清理超过5分钟的HTML预览文件
     * @return void
     */
    public function cleanOldHtmlFiles()
    {
        try {
            $htmlDir = ROOT_PATH . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'html';

            // 检查目录是否存在
            if (!is_dir($htmlDir)) {
                return;
            }

            $currentTime = time();
            $maxAge = 5 * 60; // 5分钟 = 300秒
            $deletedCount = 0;

            // 获取目录中的所有HTML文件
            $files = glob($htmlDir . DIRECTORY_SEPARATOR . '*.html');

            foreach ($files as $file) {
                // 跳过.htaccess等非HTML文件
                if (basename($file) === '.htaccess') {
                    continue;
                }

                // 检查文件修改时间
                $fileTime = filemtime($file);
                if ($fileTime === false) {
                    continue;
                }

                // 如果文件超过5分钟，则删除
                if (($currentTime - $fileTime) > $maxAge) {
                    if (unlink($file)) {
                        $deletedCount++;
                        error_log('已删除过期HTML文件: ' . basename($file));
                    } else {
                        error_log('删除HTML文件失败: ' . basename($file));
                    }
                }
            }
            if ($deletedCount > 0) {
                error_log("清理完成，共删除 {$deletedCount} 个过期HTML文件");
            }
        } catch (\Exception $e) {
            error_log('清理HTML文件时发生错误: ' . $e->getMessage());
        }
    }
}
